﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.IO;
namespace BUS
{
    public class OurRSA
    {
       
        /// <summary>
        /// property private key
        /// </summary>
        public string PrivateKeyXML
        { get; set; }

        /// <summary>
        /// property public key
        /// </summary>
        public string PublicKeyXML
        {
            get;
            set;
        }

        /// <summary>
        /// Hàm khởi tạo thuật toán RSA với kích thước khóa
        /// </summary>
        /// <param name="keysize"> kích thước khóa</param>
        public OurRSA(int keysize)
        {
            GenerateNewRSAParams(keysize);
        }
       
        /// <summary>
        /// Tạo priavte key, public key dãng xml string
        /// </summary>
        /// <param name="keysize">chiều dài khóa</param>
        private void GenerateNewRSAParams(int keysize)
        {

            RSACryptoServiceProvider rsa =
                new RSACryptoServiceProvider(keysize);

            this.PrivateKeyXML=
               rsa.ToXmlString(true);
          
            this.PublicKeyXML=
               rsa.ToXmlString(false);
      

        }

        /// <summary>
        /// Mã hóa 1 mảng byte plain với publickey
        /// </summary>
        /// <param name="publicKeyXML"></param>
        /// <param name="plainBytes"></param>
        /// <returns></returns>
        static public byte[] Encrypt(string publicKeyXML, byte[] plainBytes)
        {
            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
            rsa.FromXmlString(publicKeyXML);

            byte[] cipher=rsa.Encrypt(plainBytes, false);
            return cipher;

        }

        /// <summary>
        /// giải mã 1 cipherbyte với privatekey
        /// </summary>
        /// <param name="cipherBytes"></param>
        /// <param name="privateKey"></param>
        /// <returns></returns>
        static public byte[] Decrypt(byte[] cipherBytes, string privateKey)
        {
            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
            rsa.FromXmlString(privateKey);
            byte[] plain = rsa.Decrypt(cipherBytes, false);
            return plain;
        }

        /// <summary>
        /// Hàm hash và kí lên lên mảng byte
        /// </summary>
        /// <param name="cipherBytes"></param>
        /// <param name="privateKeyXML"></param>
        /// <returns></returns>
        public static byte[] HashAndSign(byte[] cipherBytes, string privateKeyXML)
        {
            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
            rsa.FromXmlString(privateKeyXML);

            SHA1Managed sha = new SHA1Managed();
            byte[] hashedData=sha.ComputeHash(cipherBytes);

            return rsa.SignHash(hashedData, CryptoConfig.MapNameToOID("SHA1"));
        }



        /// <summary>
        /// Hàm xác nhận chữ kí
        /// </summary>
        /// <param name="signedData"></param>
        /// <param name="signature"></param>
        /// <param name="publicKeyXML"></param>
        /// <returns></returns>
        public static bool VerifyHash(byte[] signedData,byte[] signature ,string publicKeyXML)
        {
            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
            rsa.FromXmlString(publicKeyXML);

            SHA1Managed sha = new SHA1Managed();
            byte[] hashedData = sha.ComputeHash(signedData);

            return rsa.VerifyHash(hashedData, CryptoConfig.MapNameToOID("SHA1"), signature);
        }

       
    }
}
